/* * Copyright © 2023 https://www.cestc.cn/ All rights reserved. */
package com.ffz.calcitesql.sqlparser;

import com.ffz.calcitesql.sqlparser.enums.LineNodeType;
import com.ffz.calcitesql.sqlparser.meta.LineColumnNode;
import com.ffz.calcitesql.sqlparser.nodeparser.NodeParser;
import com.ffz.calcitesql.sqlparser.vistor.SqlFieldVisitor;
import org.apache.calcite.avatica.util.Casing;
import org.apache.calcite.avatica.util.Quoting;
import org.apache.calcite.config.CalciteConnectionConfigImpl;
import org.apache.calcite.config.Lex;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.plan.ConventionTraitDef;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptTable;
import org.apache.calcite.plan.hep.HepPlanner;
import org.apache.calcite.plan.hep.HepProgramBuilder;
import org.apache.calcite.prepare.CalciteCatalogReader;
import org.apache.calcite.rel.RelRoot;
import org.apache.calcite.rel.rules.CoreRules;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParseException;
import org.apache.calcite.sql.parser.SqlParser;
import org.apache.calcite.sql.parser.impl.SqlParserImpl;
import org.apache.calcite.sql.validate.SqlConformanceEnum;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorUtil;
import org.apache.calcite.sql2rel.SqlToRelConverter;
import org.apache.calcite.sql2rel.StandardConvertletTable;
import org.apache.calcite.tools.FrameworkConfig;
import org.apache.calcite.tools.Frameworks;
import org.apache.commons.lang.StringUtils;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Hive解析.
 *
 * @author fengfazheng
 * @since 2024/1/15 15:23
 */
public class HiveSqlParser extends CommonSqlParser {
    public HiveSqlParser(){
        super();
        config=SqlParser.config().withParserFactory(SqlParserImpl.FACTORY)
                .withUnquotedCasing(Casing.UNCHANGED)
                .withQuotedCasing(Casing.UNCHANGED)
                .withCaseSensitive(false)
                .withLex(Lex.JAVA)
                .withConformance(SqlConformanceEnum.DEFAULT);
    }
    @Override
    public void parseSql(String sql) throws SqlParseException {
        // 创建一个SQL解析器
        SqlParser sqlParser = SqlParser.create(sql, config);
        SqlNode sqlNode = sqlParser.parseQuery();
//        NodeParser nodeParser=SqlNodeParserFactory.getInstance().getNodeParser(sqlNode.getKind());
//        nodeParser.parserSqlNode(sqlNode);
        SqlFieldVisitor sqlFieldVisitor = new SqlFieldVisitor();
        sqlNode.accept(sqlFieldVisitor);
        Map<String, LinkedList<LineColumnNode>> lineColumnNodeMap = sqlFieldVisitor.lineColumnNodeMap;
        for (Map.Entry<String, LinkedList<LineColumnNode>>entry:lineColumnNodeMap.entrySet()){
            String key = entry.getKey();
            List<LineColumnNode> value = entry.getValue();
            System.out.println("血缘初始字段值为："+key);
            StringBuilder lineBuidler=new StringBuilder();
            for (LineColumnNode lineColumnNode:value){
                if(LineNodeType.FUNCTION.name().equalsIgnoreCase(lineColumnNode.getType())){
                    lineBuidler.append(lineColumnNode.getFunciton())
                            .append("->");
                }else if(LineNodeType.COLUMN.name().equalsIgnoreCase(lineColumnNode.getType())
                        ||LineNodeType.ALL_COLUMN.name().equalsIgnoreCase(lineColumnNode.getType())){
                    lineBuidler.append(lineColumnNode.getName())
                            .append("(").append(lineColumnNode.getTable())
                            .append(")")
                            .append("->");
                }
            }
            if(lineBuidler.length()>2){
                lineBuidler.delete(lineBuidler.length()-2,lineBuidler.length());
            }
            System.out.println(lineBuidler);
        }
    }

}
